//******************************************************************************
// (c) Copyright  Harman Music Group Inc.  All rights reserved.
//******************************************************************************

/*******************************************************************************
*     File:   ProgramUtil.h
*******************************************************************************/

/*******************************************************************************
*   History/Customer Service Notes:
*
*       xx-xx-xxxx  Release Version 1.00
*
*******************************************************************************/

#ifndef PROGRAM_H
#define PROGRAM_H

typedef unsigned char   uint8;
typedef short           int16;
typedef unsigned short  uint16;
typedef unsigned int    uint32;


//********************************************************************
//    GLOBAL CONSTANTS
//********************************************************************
#define IsPrgLoading()        loading_prg    // 1== prg is loading
#define SetIsPrgLoading(x)    loading_prg=x

#define IsGuiProgram()        gui_prg    // 1== prg is loading
#define SetIsGuiProgram(x)    gui_prg=x

#define USE_USER_PRG_INDEXS     1       // 0 or NO if user prg indexs are not used

#define CfPresetFileVers         3     // version of the preset file
#define CardBankNameSize         12    // must be even

// Preset number order: user, factory, cf card
//
#define MAX_USER_PROGRAMS        80
#define MAX_FACT_PROGRAMS        80
#define MAX_CARD_PROGRAMS        80 // CF card presets

#define MAX_USER_BANKS      (MAX_USER_PROGRAMS/5)
#define MAX_CARD_BANKS      (MAX_CARD_PROGRAMS/5)
#define MAX_BANK_NAME       9

#define PROGRAMS_PER_BANK   5
#define USER_PROGRAM_BANK   1
#define FACT_PROGRAM_BANK   0
#define MAX_PROGRAM_NAME    11


#define MAX_FACTORY_CABS    23
#define MAX_GENETX_CABS     9
#define MAX_CAB_NAME        11
#define CAB_OFF_INDX        0

#define MAX_FACTORY_AMPS    27
#define MAX_GENETX_AMPS     9
#define MAX_AMP_NAME        11
#define AMP_OFF_INDX        0
#define GREEN     0
#define RED       1


#define MAX_EFFECTS     15          // number of post distortion modulation effects
#define MAX_PREMOD      (9)         // number of post distortion modulation effects
#define MAX_STOMPBOXES  10          // number of stompboxes
//#define MAX_LOAD_PARAMS 119

#define NUM_CAB_ZREGS               128
#define CAB_ZREG_BLOCK_SIZE         NUM_CAB_ZREGS *2

#define NUM_SPLINE_COEFS            128
#define SPLINE_COEF_BLOCK_SIZE      NUM_SPLINE_COEFS *3

#define NUM_MODEL_EQ_ZREGS          60
#define MODEL_EQ_ZREG_BLOCK_SIZE    NUM_MODEL_EQ_ZREGS *3


// For load_program(Cmd)
#define LdPrg_InitParams      0x01
#define LdPrg_DoAbort         0x02
#define LdPrg_InitAbort       0x03
#define LdPrg_NoSysxMsg       0x04
#define LdPrg_FullProgram     0x08
#define LdPrg_UseFastMethod   0x10
#define LdPrg_UpdateParams    0x20
#define LdPrg_SkipDna1        0x40

// Range values for parameters all ranges start at zero
#define ON_BYPASS_RANGE         1

// dont know if these are going to be needed
/*
// Pickup
#define PICKUP_TYPE_RANGE       2

// Wah/Whammy
#define WAH_TYPE_RANGE          2
#define WAH_MIN_RANGE           99
#define WAH_MAX_RANGE           99

// Compressor
#define COMP_ATTACK_RANGE       3
#define COMP_THRESHOLD_RANGE    99
#define COMP_RATIO_RANGE        11
#define COMP_GAIN_RANGE         20

// ISP/Whammy/Arpeggiator
#define IPS_TYPE_RANGE          3
#define IPS_LEVEL_RANGE         99
#define IPS_AMOUNT_RANGE        12
#define IPS_SCALE_RANGE         9
#define IPS_KEY_RANGE           11

// Amp Model
#define MOD_CHANNEL_RANGE       2
#define MOD_TYPE_RANGE          11
#define MOD_GAIN_RANGE          99
#define MOD_LEVEL_RANGE         99
#define ACOUSTIC_TYPE           16
#define DIRECT_TYPE             0
*/
// Cabinet
#define CABINET_TYPE_RANGE      9
#define CAB_DETUNE_RANGE        27
#define ZERO_DETUNE             24

// EQ
//#define EQ_BASS_RANGE           24
#define EQ_BASS_MIN             50
#define EQ_BASS_MAX             300
//#define EQ_MID_RANGE            24
#define EQ_MID_MIN              300
#define EQ_MID_MAX              5000
//#define EQ_HIGH_RANGE           24
#define EQ_HIGH_MIN             500
#define EQ_HIGH_MAX             8000

/*
// Gate
#define GATE_TYPE_RANGE         10
#define GATE_THRESHOLD_RANGE    20
#define GATE_ATTACK_RANGE       20
#define GATE_PLKSNS_RANGE       98

// Effects
#define EFF_TYPE_RANGE          14
#define EFF_LEVEL_RANGE         99
#define EFF_PARAM1_RANGE        99
#define EFF_PARAM2_RANGE        99
#define EFF_PARAM3_RANGE        99
#define EFF_PARAM4_RANGE        99
#define EFF_PARAM5_RANGE        99

// Delay
#define DEL_TYPE_RANGE          4
#define DEL_LEVEL_RANGE         99
#define DEL_TIME_RANGE          119
#define DEL_TIME_MIN            10
#define DEL_TIME_MAX            2000
#define DEL_FEEDBACK_RANGE      100
#define DEL_DUCKER_RANGE        99
#define DEL_BALANCE_RANGE       99
#define DEL_SPREAD_TYPE         4

// Reverb
#define REV_TYPE_RANGE          9
#define REV_LEVEL_RANGE         99
#define REV_DECAY_RANGE         10
#define REV_PREDELAY_RANGE      10
#define REV_DAMPING_RANGE       10
#define REV_BALANCE_RANGE       99

// Volume levels
#define VOLUME_PEDAL_RANGE      99

// Assignments
#define ASSIGN_PARAM_RANGE      (MAX_ASSIGN_PARAMS -1)

// LFO 1
#define LFO_PARAM_RANGE         (MAX_ASSIGN_PARAMS -1)
#define LFO_SPEED_RANGE         185
#define LFO_WAVE_RANGE          2

//FootSwitch
#define FS_TYPE_RANGE           3

// Stomp Box
#define STOMP_TYPE_RANGE         9
#define STOMP_GAIN_RANGE         99
#define STOMP_PARAM1_RANGE       99
#define STOMP_PARAM2_RANGE       99
#define STOMP_PARAM3_RANGE       99
#define STOMP_PARAM4_RANGE       99
#define STOMP_LEVEL_RANGE        99

// Talker
#define TALK_TYPE_RANGE          6

#define MAX_LINKS  8
*/

#define DEL_SPREAD_TYPE         4


//********************************************************************
//    GLOBAL MACROS
//********************************************************************

#define IsProgramLoading() loading_prg;
//********************************************************************
//    GLOBAL TYPE DEFINES / STRUCTURES
//********************************************************************
// dont know if these are going to be needed
//#define WAH_MOD_PCNT    6
//#define COMP_MOD_PCNT   6
//#define IPS_MOD_PCNT    7
//#define AMP_CH_MOD_PCNT 1
//#define EQ_CH_MOD_PCNT  1
//#define AMP1_MOD_PCNT   3
//#define CAB1_MOD_PCNT   2
//#define EQ1_MOD_PCNT    9
//#define AMP2_MOD_PCNT   4
//#define CAB2_MOD_PCNT   2
//#define EQ2_MOD_PCNT    9
//#define GATE_MOD_PCNT   5
//#define EFF_MOD_PCNT    8
//#define DEL_MOD_PCNT    9
//#define REV_MOD_PCNT    7
//#define MORPH_MOD_PCNT  3
//#define STOMP_MOD_PCNT   8
//#define VOLUME_MOD_PCNT 2
//#define ASSIGN_MOD_PCNT 20
//#define MISC_MOD_PCNT   2

enum PARAMDEFINES
{
// Pickup
   PICKUP_TYPE,

// Wah
   WAH_ONBY,
   WAH_TYPE,
   WAH_PEDAL,

// Compressor
   COMP_ONBY,
   COMP_TYPE,
   COMP_ATTACK,
   COMP_THRESHOLD,
   COMP_RATIO,
   COMP_GAIN,

// IPS/Whammy/Arpeggiator
   IPS_ONBY,
   IPS_TYPE,
   IPS_LEVEL,
   IPS_PARAM1,
   IPS_PARAM2,
   IPS_PARAM3,
   WHAM_PEDAL,             // not used anymore except for a place in OsParamArray[]

// Amp Channel
   AMP_CHANNEL,

// EQ Channel
   EQ_CHANNEL,

// Amp Model ch1
   AMP_TYPE,
   AMP_GAIN,
   AMP_LEVEL,

// Cabinet ch1
   CAB_TYPE,
   CAB_DETUNE,

// EQ ch1
   EQ_BASS_FREQ,
   EQ_BASS,
   EQ_MID_FREQ,
   EQ_MID,
   EQ_HIGH_FREQ,
   EQ_HIGH,

// Amp Model ch2
   AMP2_TYPE,
   AMP2_GAIN,
   AMP2_LEVEL,

// Cabinet ch2
   CAB2_TYPE,
   CAB2_DETUNE,

// EQ ch2
   EQ2_BASS_FREQ,
   EQ2_BASS,
   EQ2_MID_FREQ,
   EQ2_MID,
   EQ2_HIGH_FREQ,
   EQ2_HIGH,

// Gate
   GATE_ONBY,
   GATE_TYPE,
   GATE_THRESHOLD,
   GATE_ATTACK,
   GATE_PLKSNS,

// Effects
   EFF_ONBY,
   EFF_TYPE,
   EFF_LEVEL,
   EFF_PARAM1,
   EFF_PARAM2,
   EFF_PARAM3,
   EFF_PARAM4,
   EFF_PARAM5,

// Delay
   DEL_ONBY,
   DEL_TYPE,
   DEL_LEVEL,
   DEL_TIME,
   DEL_FEEDBACK,
   DEL_DUCKER,
   DEL_DUCKER_LVL,
   DEL_BALANCE,

// Reverb
   REV_ONBY,
   REV_TYPE,
   REV_LEVEL,
   REV_DECAY,
   REV_DAMPING,
   REV_PREDELAY,
   REV_BALANCE,

// Morph params
   AMP_MORPH,
   CAB_MORPH,
   LINK_MORPH,

// Stomp parameters
   STOMP_ONBY,
   STOMP_TYPE,
   STOMP_GAIN,
   STOMP_LEVEL,
   STOMP_PARAM1,
   STOMP_PARAM2,
   STOMP_PARAM3,
   STOMP_PARAM4,


// Volume levels
   VOLUME_PRE,
   VOLUME_POST,

// Assignments
   TREDAL1_PARAM,
   TREDAL1_POSITION, //This has to be one index passed the assignment param.
   TREDAL1_MIN,
   TREDAL1_MAX,

   TREDAL2_PARAM,
   TREDAL2_POSITION, //This has to be one index passed the assignment param.
   TREDAL2_MIN,
   TREDAL2_MAX,

   TREDAL3_PARAM,
   TREDAL3_POSITION, //This has to be one index passed the assignment param.
   TREDAL3_MIN,
   TREDAL3_MAX,

// LFO 1
   LFO1_PARAM,
   LFO1_POSITION, //This has to be one index passed the assignment param.
   LFO1_MIN,
   LFO1_MAX,
   LFO1_SPEED,
   LFO1_WAVE,

// LFO 2
   LFO2_PARAM,
   LFO2_POSITION, //This has to be one index passed the assignment param.
   LFO2_MIN,
   LFO2_MAX,
   LFO2_SPEED,
   LFO2_WAVE,

// Foot Switch
   FS_TYPE,

// Control Foot Switch
   CNTA_FS_TYPE,
   CNTA1_FS_PARAM,
   CNTA1_FS_POSITION, //This has to be one index passed the assignment param.
   CNTA1_FS_MIN,
   CNTA1_FS_MAX,

   CNTA2_FS_PARAM,
   CNTA2_FS_POSITION, //This has to be one index passed the assignment param.
   CNTA2_FS_MIN,
   CNTA2_FS_MAX,

   CNTA3_FS_PARAM,
   CNTA3_FS_POSITION, //This has to be one index passed the assignment param.
   CNTA3_FS_MIN,
   CNTA3_FS_MAX,

   FS_TAPIT_MODE,

// Modified allows the editor to know when program has been saved by the box
   MODIFIED,
   DEL_SPREAD,
   PICKUP_ONBY,
   EQ_ONBY,
   EQ_PRESENCE,
   EQ2_ONBY,
   EQ2_PRESENCE,
   VSWITCH_STATE,
   PRESET_LEVEL,

// Control Foot Switch  B
   CNTB_FS_TYPE,
   CNTB1_FS_PARAM,
   CNTB1_FS_POSITION, //This has to be one index passed the assignment param.
   CNTB1_FS_MIN,
   CNTB1_FS_MAX,

   CNTB2_FS_PARAM,
   CNTB2_FS_POSITION, //This has to be one index passed the assignment param.
   CNTB2_FS_MIN,
   CNTB2_FS_MAX,

   CNTB3_FS_PARAM,
   CNTB3_FS_POSITION, //This has to be one index passed the assignment param.
   CNTB3_FS_MIN,
   CNTB3_FS_MAX,

// Control Foot Switch  C
   CNTC_FS_TYPE,
   CNTC1_FS_PARAM,
   CNTC1_FS_POSITION, //This has to be one index passed the assignment param.
   CNTC1_FS_MIN,
   CNTC1_FS_MAX,

   CNTC2_FS_PARAM,
   CNTC2_FS_POSITION, //This has to be one index passed the assignment param.
   CNTC2_FS_MIN,
   CNTC2_FS_MAX,

   CNTC3_FS_PARAM,
   CNTC3_FS_POSITION, //This has to be one index passed the assignment param.
   CNTC3_FS_MIN,
   CNTC3_FS_MAX,

// VSwitch ON OFF links
   VSW_FS_TYPE,
   VSW1_FS_PARAM,
   VSW1_FS_POSITION, //This has to be one index passed the assignment param.
   VSW1_FS_MIN,
   VSW1_FS_MAX,

   VSW2_FS_PARAM,
   VSW2_FS_POSITION, //This has to be one index passed the assignment param.
   VSW2_FS_MIN,
   VSW2_FS_MAX,

   VSW3_FS_PARAM,
   VSW3_FS_POSITION, //This has to be one index passed the assignment param.
   VSW3_FS_MIN,
   VSW3_FS_MAX,

// VSwitch pedal Assignments
   VSW_TREDAL1_PARAM,
   VSW_TREDAL1_POSITION, //This has to be one index passed the assignment param.
   VSW_TREDAL1_MIN,
   VSW_TREDAL1_MAX,

   VSW_TREDAL2_PARAM,
   VSW_TREDAL2_POSITION, //This has to be one index passed the assignment param.
   VSW_TREDAL2_MIN,
   VSW_TREDAL2_MAX,

   VSW_TREDAL3_PARAM,
   VSW_TREDAL3_POSITION, //This has to be one index passed the assignment param.
   VSW_TREDAL3_MIN,
   VSW_TREDAL3_MAX,


   MAX_LOAD_PARAMS // size of PARAMDEFINES
};

struct preset_
{
   uint16   params[MAX_LOAD_PARAMS];// array of parameter values
   uint8    name[MAX_PROGRAM_NAME]; // name of program
};
typedef struct preset_ PRESET;

struct genetx_cabinet_
{
   uint16   zreg_data[NUM_CAB_ZREGS];// array of parameter values
   uint8    name[MAX_CAB_NAME]; // name of program
};
typedef struct genetx_cabinet_ GENETX_CABINET;

struct genetx_amp_tone_
{
   uint16   bass_freq,
            mid_freq,
            hi_freq;

   uint16   bass_level,
            mid_level,
            hi_level,
            presence,
            amp_gain,
            amp_level;

};
typedef struct genetx_amp_tone_ GENETX_AMP_TONE;

struct genetx_amp_range_
{
   uint32 Gain_Max,
          Gain_Min,
          Level_Max,
          Level_Min;

};
typedef struct genetx_amp_range_ GENETX_AMP_RANGE;

struct EQBandCoef_
{
   uint32   A0,
            A1,
            A2,
            B1,
            B2;
};
typedef struct EQBandCoef_ EQBANDCOEF;


struct genetx_amp_
{
   uint32   spline_coef_data[NUM_SPLINE_COEFS],// array of parameter values
            model_eq_zreg_data[NUM_MODEL_EQ_ZREGS];
   GENETX_AMP_TONE  def_tone;
   GENETX_AMP_RANGE def_range;
   uint8 name[MAX_AMP_NAME]; // name of program
};
typedef struct genetx_amp_ GENETX_AMP;

struct program_eq_
{
   EQBANDCOEF     GrnBassCoef;
   EQBANDCOEF     GrnMidCoef;
   EQBANDCOEF     GrnTrebCoef;
   EQBANDCOEF     RedBassCoef;
   EQBANDCOEF     RedMidCoef;
   EQBANDCOEF     RedTrebCoef;
};
typedef struct program_eq_  PROGRAM_EQ;

struct program_
{
   PRESET         Prg;
   GENETX_AMP     Amps[2];
   GENETX_CABINET Cabs[2];
   PROGRAM_EQ     ToneEQ;

};
typedef struct program_ PROGRAM;

struct globals_
{
   // globals stuff
   uint16   stero_mono,     //STEREO_MONO
            bounce,         //PRESETBOUNCEBACK
            midi_channel,   //MIDI_CHANNEL
            midi_merge,     //MIDI_MERGE
            vol_ped_update; //VOL_PEDAL_UPDATE
   int16    vswitch;        //VSWITCH_SENSITIVITY
   // tuner stuff
   uint16  tuner_ref;   //Tuner Reference Frequency

   // pedal calibration
   int16   tredal_pwm;

   int16   tredal_min;

   int16   tredal_max;

   uint16  DrumMidi;       // drum midi sent out or not.
   uint16  DrumKitDefault;

   // recorder USB stuff
   uint16  mic_routing;
   uint16  line_routing;
   uint16  usb12_source;
   uint16  usb34_source;
   uint16  usb_mix;
   uint16  usb12_level;
   uint16  usb34_level;

   uint16  HandsFreeDefault;

   int16   vswitch_zero;

};
typedef struct globals_ GLOBALS;


//********************************************************************
//    GLOBAL VARIABLES
//********************************************************************
extern PROGRAM CurrentProgram;   // hold the current params and name
extern PROGRAM MidiProgram;      // hold the current params and name
extern PROGRAM TempProgram;      // hold the current params and name
extern PROGRAM CfCardPresetBufA[MAX_CARD_PROGRAMS/2];
extern PROGRAM CfCardPresetBufB[MAX_CARD_PROGRAMS- (MAX_CARD_PROGRAMS/2)];


extern GENETX_AMP       save_amp;
extern GENETX_CABINET   save_cab;

extern EQBANDCOEF sEqCoefs;
extern PROGRAM_EQ EQTables[MAX_FACT_PROGRAMS];

// 5 models are needed, two for cur prg, two for the copied prg, 1 for testing for custom
extern GENETX_AMP  CustAmpModel[5];  // when user changes amp models, copy to here first
extern GENETX_CABINET CustCabModel[5];  // when user changes cab models, copy to here first

#if USE_USER_PRG_INDEXS == 1
extern uint16 user_prog_indexes[MAX_USER_PROGRAMS];
extern uint16 card_prog_indexes[MAX_CARD_PROGRAMS];
extern uint16 TempIndexes[MAX_USER_PROGRAMS];
#endif

extern uint16 loading_prg;
extern uint16 gui_prg;
extern uint16 PresetChanged;
//extern uint16 LoadFullProgram;
//extern uint16 UseFastMethod;
extern uint16 IsCustomSaved;

extern const uint16 fac_cab_default[MAX_FACTORY_AMPS];

extern const char EmptyStr[];
//********************************************************************
//    GLOBAL FUNCTION PROTOTYPES
//********************************************************************

void
InitEvList(void);

void
ClearParamFlags(void);

void
LoadProgram(uint16 PresetNum, uint8 Cmd);

void
InitParamData(uint16 PresetNum, PROGRAM *PrgBuf);

void
LoadParams(uint8 DoAbort);

void
SetParams(PROGRAM  *PrgBuf);

void
GetParams(PROGRAM  *PrgBuf);

uint8
SaveProgram(uint16 StoToPrgNum, PROGRAM  *PrgBuf, uint8 UpdateParams);

void
PrmUtilGetPrgName(char *temp_name, uint16 PresetNum);

uint8
ResetUserPrograms(void);

uint8
ResetUserSettings(void);

uint8
LoadUserSettings(void);

void PUtilInitCardIdxs(void);
void PUtilCardError(void);
void PUtilWrCardBank(int16 CBankNum);
void PUtilWrCardIndexs(void);
void PUtilWrAllUserPresetsToCF();
void PUtilLoadCFPresets(void);


#ifdef __cplusplus
extern "C"
{
#endif

void
load_amp_data(uint16 CurValue, uint16 channel, GENETX_AMP *Amp_ptr);

void
load_cab_data(uint16 CurValue, uint16 channel, GENETX_CABINET *Cab_ptr);

void
CalcEqCoefs(uint8 GainParam, uint16 FreqParam);

void
CopyToCustom(uint8 BufN);

void
CopyFromCustom(uint8 BufN);

void
CalcRotoryCoefs(uint8 CurValue, float  *f_ptr);

void
CalcStompCoefs(uint8 GainParam, uint8 FreqParam);

void
SaveAmpCab(uint16 location, char *Name);

void
LoadAmpNameList(void);

void
LoadCabNameList(void);

void
LoadCustomName(void);

void
CheckAmpCab(void);

void
calc_prg_eq(struct program_eq_  *prg_eq, PROGRAM  *PrgBuf);


#ifdef __cplusplus
}
#endif

void
read_morphed_amp(GENETX_AMP *morph_amp);

void
read_morphed_cab(GENETX_CABINET *morph_cab);

uint8
MidiSendParams(void);

uint8
MidiSendGlobals(void);

/*
// ProgramUtil.h shows the structures we use to process a preset.
// The following is a code snippet showing how we load a preset.

PrgBuf->Prg = fact_prog_table[PresetNum];

// load all the amp and cab
load_amp_data( PrgBuf->Prg.params[AMP_TYPE],  GREEN, &PrgBuf->Amps[0] );
load_cab_data( PrgBuf->Prg.params[CAB_TYPE], GREEN, &PrgBuf->Cabs[0] );
load_amp_data( PrgBuf->Prg.params[AMP2_TYPE], RED,   &PrgBuf->Amps[1] );
load_cab_data( PrgBuf->Prg.params[CAB2_TYPE], RED,   &PrgBuf->Cabs[1] );

// load eq table
PrgBuf->ToneEQ = EQTables[PresetNum];
*/

#endif


